package com.wskj.common.utils.wx;

import cn.hutool.core.codec.Base64;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wskj.common.core.domain.AjaxResult;
import com.wskj.common.utils.common.AssertUtils;
import com.wskj.common.utils.common.HttpUtils;
import lombok.extern.slf4j.Slf4j;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.spec.AlgorithmParameterSpec;
import java.util.HashMap;
import java.util.Map;

/**
 * Filename: WechatUtils.java
 * Description: 微信认证工具类
 * Copyright: Copyright (c) 2016-2019 All Rights Reserved.
 * Company: wsdz.com Inc.
 *
 * @author: gunk
 * @version: 1.0
 * Create at: 2022/8/17 14:04
 * <p>
 * Modification History:
 * Date Author Version Description
 * ------------------------------------------------------------------
 * 2022/8/17 guqk 1.0 1.0 Version
 */
@Slf4j
public class WechatUtils {

    /**
     * 请求的网址
     */
    public static String WX_LOGIN_URL = "https://api.weixin.qq.com/sns/jscode2session";

    /**
     * 固定参数
     */
    public static String WX_LOGIN_GRANT_TYPE = "authorization_code";

    /**
     * 获取微信小程序openid
     *
     * @param appId  微信appId
     * @param secret 微信秘钥
     * @param code   微信code(临时登录获取)
     * @return
     */
    public static String getOpenid(String appId, String secret, String code) {
        String url = String.format("https://api.weixin.qq.com/sns/jscode2session?appid=%s&&secret=%s&&js_code=%s" +
                "&grant_type=authorization_code", appId, secret, code);
        String resultInfo = HttpUtils.doGet(url);
        log.info("小程序登录获取结果:" + resultInfo);
        String openid = JSONObject.parseObject(resultInfo).getString("openid");
        return openid;
    }

    /**
     * 解密手机号
     *
     * @param decryptData 加密手机号（微信返回）
     * @param key         session_key
     * @param iv          iv（微信返回）
     * @return
     */
    public static AjaxResult decryptS5(String decryptData, String key, String iv) {
        try {
            byte[] encData = Base64.decode(decryptData);
            byte[] ivs = Base64.decode(iv);
            byte[] keys = Base64.decode(key);
            AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivs);
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec keySpec = new SecretKeySpec(keys, "AES");
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
            return AjaxResult.success("获取手机号失败", JSON.parseObject(new String(cipher.doFinal(encData), "UTF-8")));
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("获取手机号失败");
        }
    }

    /**
     * 获取微信小程序的手机号
     *
     * @param appId  微信appId
     * @param secret 微信秘钥
     * @param code   微信code(获取手机号code)
     * @return
     */
    public static String getWxPhoneNumber(String appId, String secret, String code) {

        String mpToken = SenInfoCheckUtils.getMpToken(appId, secret);
        String url = String.format("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=%s", mpToken);

        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("code", code);
        String result = HttpUtil.post(url, JSONUtil.toJsonStr(requestBody));

        cn.hutool.json.JSONObject jsonObject = JSONUtil.parseObj(result);

        String errcode = jsonObject.getStr("errcode");

        AssertUtils.isTrue(errcode.equals("0"), "手机号获取失败");
        cn.hutool.json.JSONObject phoneInfo = jsonObject.getJSONObject("phone_info");
        String purePhoneNumber = phoneInfo.getStr("purePhoneNumber");
        return purePhoneNumber;

    }

    /**
     * 获取不限制的小程序码
     *
     * @param appId      微信appId
     * @param secret     微信秘钥
     * @param page       页面路径
     * @param inviteCode 参数
     * @return
     */
    public static byte[] getMiniCode(String appId, String secret, String page, String inviteCode, Boolean checkPath, String envVersion) {

        String mpToken = SenInfoCheckUtils.getMpToken(appId, secret);
        String url = String.format("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%s", mpToken);

        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("page", page);
        requestBody.put("scene", inviteCode);

        // 默认是true，检查page 是否存在，为 true 时 page 必须是已经发布的小程序存在的页面（否则报错）；为 false 时允许小程序未发布或者 page 不存在， 但page 有数量上限（60000个）请勿滥用。
        requestBody.put("check_path", checkPath);

        // 要打开的小程序版本。正式版为 "release"，体验版为 "trial"，开发版为 "develop"。默认是正式版
        requestBody.put("env_version", envVersion);

        // 生成小程序码
        requestBody.put("width", 280);

        byte[] bytes = HttpRequest.post(url).body(JSONUtil.toJsonStr(requestBody)).execute().bodyBytes();
        return bytes;
    }
}
